package com.tender.shiro.matcher;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import com.tender.constants.Constants;

import java.util.concurrent.TimeUnit;

public class RetryLimitCredentialsMatcher extends HashedCredentialsMatcher {

    private RedissonClient redissonClient;

    private static final Long PASSWORD_TRY_LIMIT = Constants.PASSWORD_TRY_LIMIT;

    /**
     * @Description 构造函数
     * @param hashAlgorithmName 匹配次数
     * @return
     */
    public RetryLimitCredentialsMatcher(String hashAlgorithmName,RedissonClient redissonClient) {
        super(hashAlgorithmName);
        this.redissonClient = redissonClient;
    }

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        String loginName = token.getPrincipal().toString();
        // 获得缓存
        RAtomicLong atomicLong = redissonClient.getAtomicLong(loginName);
        long retryFlag = atomicLong.get();
        //判断次数
        if (retryFlag > PASSWORD_TRY_LIMIT){
            //超过次数设计10分钟后重试
            atomicLong.expire(Constants.BLOCK_LOGIN_TIME, TimeUnit.MINUTES); // 设置 atomicLong 的过期时间为 10 min
            throw new ExcessiveAttemptsException("密码错误5次，请10分钟以后再试");
        }
        // 累加次数
        atomicLong.incrementAndGet();
        atomicLong.expire(Constants.BLOCK_LOGIN_TIME, TimeUnit.MINUTES); // 重新设置 atomicLong 的过期时间为 10 min
        //密码校验
        boolean flag =  super.doCredentialsMatch(token, info);
        if (flag){
            // 校验成功删除限制
            atomicLong.delete();
        }
        return flag;
    }
}
